#include "CHardware.h"
#include "CComputer.h"
#include "CSensor.h"
#include "CHardware.HDD.h"
#include <msclr/gcroot.h>
#include <QDebug>
#using "OpenHardwareMonitorLib.dll"

using namespace msclr;
using namespace System::Runtime::InteropServices;

namespace NOpenHardwareMonitor {

namespace NHardware {

class CHardwarePrivate
{
public:
	gcroot<OpenHardwareMonitor::Hardware::IHardware^> mHardware;
};


CHardware::CHardware(CComputer* Computer, const qint32& Index)
	: QObject(Computer)
	, d_ptr(new CHardwarePrivate())
{
	Q_D(CHardware);
	d->mHardware = (*(gcroot<OpenHardwareMonitor::Hardware::Computer^>*)Computer->GetHandle())->Hardware[Index];
}

CHardware::CHardware(CHardware* Hardware, const qint32& Index)
	: QObject(Hardware)
	, d_ptr(new CHardwarePrivate())
{
	Q_D(CHardware);
	d->mHardware = (*(gcroot<OpenHardwareMonitor::Hardware::IHardware^>*)Hardware->GetHandle())->SubHardware[Index];
}

CHardware::~CHardware()
{  }

void CHardware::Release()
{ delete this; }

void CHardware::Update()
{ Q_D(CHardware); d->mHardware->Update(); }

QString CHardware::GetReport() const
{
	Q_D(const CHardware);

	char* m_ReportChar = (char*)(void*)Marshal::StringToHGlobalAnsi(d->mHardware->GetReport());
	return QString(m_ReportChar);
}

QString CHardware::GetName() const
{
	Q_D(const CHardware);

	char* m_NameChar = (char*)(void*)Marshal::StringToHGlobalAnsi(d->mHardware->Name);
	return QString(m_NameChar);
}

CHardware::EType CHardware::GetType() const
{ Q_D(const CHardware); return (CHardware::EType)(qint32)d->mHardware->HardwareType; }

QString CHardware::GetIdentifier() const
{
	Q_D(const CHardware);

	char* m_IdentifierChar = (char*)(void*)Marshal::StringToHGlobalAnsi(d->mHardware->Identifier->ToString());
	return QString(m_IdentifierChar);
}

qint32 CHardware::GetHashCode() const
{ Q_D(const CHardware); return d->mHardware->GetHashCode(); }

qint32 CHardware::GetSensorCount() const
{ Q_D(const CHardware); return d->mHardware->Sensors->Length; }

ISensor* CHardware::GetSensor(const qint32& Index)
{ Q_D(CHardware); return new CSensor(this, Index); }

qint32 CHardware::GetSubHardwareCount() const
{ Q_D(const CHardware); return d->mHardware->SubHardware->Length; }

IHardware* CHardware::GetSubHardware(const qint32& Index)
{ Q_D(CHardware); return new CHardware(this, Index); }

IHDD* CHardware::GetHDD()
{
	Q_D(CHardware);
	if (d->mHardware->HardwareType != OpenHardwareMonitor::Hardware::HardwareType::HDD) return nullptr;
	return new CHDD(this, GetIdentifier());
}

void* CHardware::GetHandle() const
{ Q_D(const CHardware); return (void*)&d->mHardware; }


}}